//============================================================================================
/**
 * @file	poke_clact.c
 * @brief	ポケモンセルアクター
 * @author	Nozomu Saito
 */
//============================================================================================

#include "common.h"
#include "system/arc_tool.h"
#include "system/arc_util.h"
#include "system/clact_util.h"
#include "../trainer_card/trainer_case.naix"

#include "poke_clact.h"

#include "field/pair_poke_no.h"
#include "..\..\data\mmodel\mmodel.naix"	//アーカイブID
#include "system/gra_tool.h"

#include "poketool/monsno.h"
#include "poketool/poke_tool.h"
#include "field/pair_poke_idx.h"

#include "pokethlon_poke.naix"

#define POKE_PALETTE_SIZE	(16*2)

#define PCLACT_SLOT_MAX	(16)
#define RESOURCE_NUM	(4)
#define ONE_CHR_BYTE	(32)

#define POKE_MAX_SIZE	((8*8)*ONE_CHR_BYTE)	//8x8キャラ（64x64dot）

//** CharManager PlttManager用 **//
///#define TR_CARD_CHAR_CONT_NUM				(1)
///#define TR_CARD_CHAR_VRAMTRANS_MAIN_SIZE	(2048)
///#define TR_CARD_CHAR_VRAMTRANS_SUB_SIZE		(0)
///#define TR_CARD_PLTT_CONT_NUM				(2)

#define POKE_PALETTE_NUM					(1)	//パレット1本

typedef enum{
	PCLACT_SET_LOAD_TRANS,
	PCLACT_SET_SET_ACT,
}PCLACT_SET_SEQ;

typedef struct PCLACT_tag
{
	CLACT_U_RES_OBJ_PTR 	ResObjTbl[RESOURCE_NUM];		// リソースオブジェテーブル
	CLACT_WORK_PTR			ClActWorkPtr;
	MONS_INFO				MonsInfo;
	int Space;
	BOOL ChinkFlg;
}PCLACT;

typedef struct PCLACT_CNT_tag
{
	int HeapID;				//ヒープＩＤ
	u16 PokeNum;			//管理ポケモンアクター数
	u16 NowNum;			//現在登録数

	BOOL	ChinkFlg;		//TRUE:サイズが大きいポケモンのキャラを上に１キャラ詰めるモード
	BOOL	ActSetFlg;		//アクターセットが終了したかどうかのフラグ	TRUE:終了	FALSE:終了していない

	BOOL ActSetUse;			//TRUE:自前のアクターセット　FALSE：外部アクターセット
	CLACT_SET_PTR 			ClActSet;				// セルアクターセット
	CLACT_SET_PTR 			ClActSetPtr;			// 参照セルアクターセット
	CLACT_U_EASYRENDER_DATA	RendData;				// 簡易レンダーデータ
	CLACT_U_RES_MANAGER_PTR	ResMan[RESOURCE_NUM];		// リソースマネージャ

	PCLACT_PTR			PokeClActTbl;				//ポケモンセルアクターテーブル
/**
	ARCHANDLE*			CharHandle;
	ARCHANDLE*			PlttHandle;
	ARCHANDLE*			CellHandle;
	ARCHANDLE*			AnmHandle;
*/
///	void *PalDataBuf[TR_CARD_BADGE_ACT_MAX];		//パレットデータTR_CARD_BADGE_ACT_MAX分
///	NNSG2dPaletteData *PalData[TR_CARD_BADGE_ACT_MAX];	//パレットデータTR_CARD_BADGE_ACT_MAX分
	u8 CharTempBuff[POKE_MAX_SIZE];

}PCLACT_CNT;

typedef struct PCLACT_SET_WORK_tag
{
	u16 EntryNum;
	u16 No;
	int StartIdx;
	PCLACT_SET_SEQ		Seq;
	PCLACT_CNT_PTR		CntPtr;
	PCLACT_SET_PARAM	Param;
	MONS_INFO InfoTbl[PCLACT_SLOT_MAX];
}PCLACT_SET_WORK;

//前方宣言

static void LoadTrance(PCLACT_CNT_PTR cnt_ptr, CLACT_U_RES_OBJ_PTR *res_obj_tbl,
		const MONS_INFO *inMonsInfo, const NNS_G2D_VRAM_TYPE inVramType,
		const u8 inActID, const BOOL inTrans);
static void SetPCLActor( PCLACT_CNT_PTR cnt_ptr, const int inBGPriority, const BOOL inTrans,
							const NNS_G2D_VRAM_TYPE inDrawArea, const u8 inActID, const u8 inEntryPoint );
static void PLCActorSetTask(TCB_PTR tcb, void* work);
static BOOL SetSeq(PCLACT_SET_WORK *work);
static u8 GetSpaceHeight(PCLACT_PTR poke_ptr);
static u8 CheckChar(u8 *data, const int inOfs);
static int GetMonsArcIdx(const int inMonsNo, const u16 inFormNo, const int inSex);

//--------------------------------------------------------------------------------------------
/**
 * ポケモンセルアクターコントローラー作成
 *
 * @param	inHeapID			ヒープＩＤ
 *
 * @return	PCLACT_CNT_PTR		ポケモンセルアクターコントローラーポインタ
 */
//--------------------------------------------------------------------------------------------
PCLACT_CNT_PTR PCLACT_Create(const int inHeapID)
{
	PCLACT_CNT_PTR cnt_ptr;
	cnt_ptr = sys_AllocMemory(inHeapID, sizeof(PCLACT_CNT));
	cnt_ptr->HeapID = inHeapID;

	return cnt_ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンセルアクター初期化（通常必要なＯＡＭ初期化とかは含まないので、各々で行ってもらう）
 *
 * @param	PCLACT_CNT_PTR		ポケモンセルアクターコントローラーポインタ
 * @param	inPokeNum			登録ポケモン最大数
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_Init(PCLACT_CNT_PTR cnt_ptr, const u8 inPokeNum, CLACT_SET_PTR pClActSet)
{
	int i;
	GF_ASSERT_MSG (inPokeNum <= PCLACT_SLOT_MAX,"スロットオーバー\n");
	cnt_ptr->PokeNum = inPokeNum;
	cnt_ptr->NowNum = 0;
	cnt_ptr->ActSetFlg = FALSE;
	cnt_ptr->ChinkFlg = 0;

	cnt_ptr->PokeClActTbl = sys_AllocMemory(cnt_ptr->HeapID, sizeof(PCLACT)*inPokeNum);

	//アクターセットの外部指定がない場合は自分で用意する
	if (pClActSet == NULL){
		//セルアクター初期化
		cnt_ptr->ClActSet = CLACT_U_SetEasyInit( cnt_ptr->PokeNum, &cnt_ptr->RendData, cnt_ptr->HeapID );
		cnt_ptr->ClActSetPtr = cnt_ptr->ClActSet;
		cnt_ptr->ActSetUse = TRUE;
	}else{
		//外部アクターセットに依存
		cnt_ptr->ClActSetPtr = pClActSet;
		cnt_ptr->ActSetUse = FALSE;
	}
	//リソースマネージャー初期化
	for(i=0;i<RESOURCE_NUM;i++){		//リソースマネージャー作成
		cnt_ptr->ResMan[i] = CLACT_U_ResManagerInit(cnt_ptr->PokeNum, i, cnt_ptr->HeapID);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンセルアクター解放関数		(レンダラの破棄、キャラ・パレットマネージャの破棄は行わない)
 *
 * @param	cnt_ptr			ポケモンセルアクターコントローラーポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_Free(PCLACT_CNT_PTR cnt_ptr)
{
	u8 i;
	for(i=0;i<cnt_ptr->PokeNum;i++){
		// キャラ転送マネージャー破棄
		CLACT_U_CharManagerDelete(cnt_ptr->PokeClActTbl[i].ResObjTbl[CLACT_U_CHAR_RES]);
		// パレット転送マネージャー破棄
		CLACT_U_PlttManagerDelete(cnt_ptr->PokeClActTbl[i].ResObjTbl[CLACT_U_PLTT_RES]);
	}

	// キャラ・パレット・セル・セルアニメのリソースマネージャー破棄
	for(i=0;i<RESOURCE_NUM;i++){
		CLACT_U_ResManagerDelete(cnt_ptr->ResMan[i]);
	}

	sys_FreeMemoryEz(cnt_ptr->PokeClActTbl);

	if (cnt_ptr->ActSetUse){
		// セルアクターセット破棄
		CLACT_DestSet(cnt_ptr->ClActSet);
	}
	sys_FreeMemoryEz(cnt_ptr);


	//OAMレンダラー破棄
///	REND_OAM_Delete();

///	DeleteCharManager();
///	DeletePlttManager();

}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンセルアクターセットタスクリクエスト
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 * @param	inEntryNum		登録数
 * @param	inInfoTbl		モンスター情報
 * @param	inParam			アクターセットパラム
 * @param	inTcbPri		タスクプライオリティ
 * @param	inBaseResID		ベースリソースID
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_SetPokeClActor(PCLACT_CNT_PTR cnt_ptr, const int inEntryNum,
		const MONS_INFO *inInfoTbl,
		const PCLACT_SET_PARAM *inParam, const int inTcbPri, const int inBaseResID)
{
	int i;
	PCLACT_SET_WORK * work = sys_AllocMemoryLo(cnt_ptr->HeapID, sizeof(PCLACT_SET_WORK));
	work->EntryNum = inEntryNum;
	work->CntPtr = cnt_ptr;
	work->Param = *inParam;
	work->Seq = PCLACT_SET_LOAD_TRANS;
	work->StartIdx = inBaseResID;
	work->No = 0;

	//アクターセットフラグを落とす

	cnt_ptr->ActSetFlg = FALSE;

	for(i=0;i<inEntryNum;i++){
		work->InfoTbl[i] = inInfoTbl[i];
	}

	TCB_Add(PLCActorSetTask, work, inTcbPri);
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンアクターセットタスク終了チェック関数
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 *
 * @return	BOOL			TRUE：終了	FALSE：継続
 */
//--------------------------------------------------------------------------------------------
BOOL PCLACT_CheckActSetTask(PCLACT_CNT_PTR	cnt_ptr)
{
	return cnt_ptr->ActSetFlg;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンアクターを返す
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 * @param	inIndex			インデックス
 *
 * @return	PCLACT_PTR		ポケモンアクターポインタ
 */
//--------------------------------------------------------------------------------------------
PCLACT_PTR PCLACT_GetPclActPtr(PCLACT_CNT_PTR cnt_ptr, const u8 inIndex)
{
	GF_ASSERT(inIndex < cnt_ptr->PokeNum)
	return &(cnt_ptr->PokeClActTbl[inIndex]);
}

//--------------------------------------------------------------------------------------------
/**
 * セルアクターポインタを返す
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 * @param	inIndex			インデックス
 *
 * @return	CLACT_WORK_PTR	セルアクターポインタ
 */
//--------------------------------------------------------------------------------------------
CLACT_WORK_PTR PCLACT_GetClActWorkPtrByIdx(PCLACT_CNT_PTR cnt_ptr, const u8 inIndex)
{
	GF_ASSERT(inIndex < cnt_ptr->PokeNum);
	return cnt_ptr->PokeClActTbl[inIndex].ClActWorkPtr;
}

//--------------------------------------------------------------------------------------------
/**
 * セルアクターポインタを返す
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 *
 * @return	CLACT_WORK_PTR	セルアクターポインタ
 */
//--------------------------------------------------------------------------------------------
CLACT_WORK_PTR PCLACT_GetClActWorkPtr(PCLACT_PTR poke_ptr)
{
	return poke_ptr->ClActWorkPtr;
}

//--------------------------------------------------------------------------------------------
/**
 * モンスター情報取得
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 *
 * @return	mons_info		モンスター情報
 */
//--------------------------------------------------------------------------------------------
const MONS_INFO *PCLACT_GetMonsInfo(PCLACT_PTR poke_ptr)
{
	return &poke_ptr->MonsInfo;
}

//--------------------------------------------------------------------------------------------
/**
 * 描画関数
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_Draw(PCLACT_CNT_PTR cnt_ptr)
{
	if (cnt_ptr->ActSetUse){
		CLACT_Draw( cnt_ptr->ClActSet );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * パレットデータを取得		フォルムとかに未対応（現在じゃモンスターナンバーでしか取れない）
 *
 * @param	inMonsInfo		モンスタ情報
 * @param	inHeapID		ヒープID
 * @param	outBuff			データ格納バッファ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_GetPalData(const MONS_INFO *inMonsInfo, const int inHeapID, u8 *outBuff)
{
	void *pFile;
	u8 *start;
	NNSG3dResTex *tex;
	{
		//アーカイブインデックス取得
		int arc_idx = GetMonsArcIdx(inMonsInfo->MonsNo, inMonsInfo->Form, inMonsInfo->Sex);
		//連れ歩きポケモンのテクスチャを読み込んでくる
		pFile = ArchiveDataLoadMalloc(	ARC_MMODEL, arc_idx, inHeapID );
	}

	// テクスチャファイルを取得
	tex = NNS_G3dGetTex((NNSG3dResFileHeader*) pFile );

	//パレットロウデータ取得
	start = (u8*)tex + tex->plttInfo.ofsPlttData;
	//レアかどうかでオフセット変更
	if (inMonsInfo->Rare){
		start = &start[POKE_PALETTE_SIZE];
	}

	//パレットデータコピー
	MI_CpuCopy8(start, outBuff, POKE_PALETTE_SIZE);

	sys_FreeMemoryEz( pFile );
}

//--------------------------------------------------------------------------------------------
/**
 * パレット変更
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 * @param	inIdx			インデックス
 * @param	inVramType		VRAMタイプ
 * @param	inPalData		パレットデータ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_ChangePalette(PCLACT_CNT_PTR cnt_ptr, const u8 inIdx, const NNS_G2D_VRAM_TYPE inVramType, u16 *inPalData )
{
	const NNSG2dImagePaletteProxy *pal_proxy;
	NNSG2dImageProxy	*img_proxy;
	u32 vram;
	BOOL main_trans = FALSE;
	BOOL sub_trans = FALSE;

	//VRAMタイプをチェック
	if (inVramType == NNS_G2D_VRAM_TYPE_MAX){
		main_trans = TRUE;
		sub_trans = TRUE;
	}else{
		if (inVramType == NNS_G2D_VRAM_TYPE_2DMAIN){
			main_trans = TRUE;
		}else{
			sub_trans = TRUE;
		}
	}

	//イメージプロキシ取得
	img_proxy = CLACT_U_CharManagerGetProxy(
			cnt_ptr->PokeClActTbl[inIdx].ResObjTbl[CLACT_U_CHAR_RES]);
	//パレットプロキシ取得
	pal_proxy = CLACT_U_PlttManagerGetProxy(
			cnt_ptr->PokeClActTbl[inIdx].ResObjTbl[CLACT_U_PLTT_RES], img_proxy);

	DC_FlushRange( inPalData, POKE_PALETTE_SIZE );	//転送するパレット部分をフラッシュ
	if (main_trans){
		vram = NNS_G2dGetImagePaletteLocation(pal_proxy, NNS_G2D_VRAM_TYPE_2DMAIN);
		GX_LoadOBJPltt( inPalData, vram, POKE_PALETTE_SIZE );	//32byte 1Palette
	}
	if (sub_trans){
		vram = NNS_G2dGetImagePaletteLocation(pal_proxy, NNS_G2D_VRAM_TYPE_2DSUB);
		GXS_LoadOBJPltt( inPalData, vram, POKE_PALETTE_SIZE );	//32byte 1Palette;
	}
}

//--------------------------------------------------------------------------------------------
/**
 * キャラ・パレット等のロードと転送
 *
 * @param	res_man			リソースマネージャポインタ
 * @param	res_obj_tbl		リソースＯＢＪテーブル
 * @param	inMonsInfo		ポケモン情報ポインタ
 * @param	inVramType		ＶＲＡＭタイプ
 * @param	inActID			アクターＩＤ
 * @param	inTrans			ＶＲＡＭ転送フラグ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void LoadTrance(PCLACT_CNT_PTR cnt_ptr, CLACT_U_RES_OBJ_PTR *res_obj_tbl,
		const MONS_INFO *inMonsInfo, const NNS_G2D_VRAM_TYPE inVramType, const u8 inActID, const BOOL inTrans)
{
	int char_arc_idx;
	int cel_arc_idx;
	int alanm_arc_idx;

	if (inTrans){
		if ( inMonsInfo->CellType ){
			char_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_64t_NCGR;
			cel_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_64t_NCER;
			alanm_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_64t_NANR;
		}else{
			char_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_32t_NCGR;
			cel_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_32t_NCER;
			alanm_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_32t_NANR;
		}
	}else{
		if ( inMonsInfo->CellType ){
			char_arc_idx = NARC_pokethlon_poke_pkthln_poke64_NCGR;
			cel_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_64_NCER;
			alanm_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_64_NANR;
		}else{
			char_arc_idx = NARC_pokethlon_poke_pkthln_poke32_NCGR;
			cel_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_32_NCER;
			alanm_arc_idx = NARC_pokethlon_poke_pkthln_pokeact_32_NANR;
		}
	}

	//ポケモン情報から、キャラ、パレット、セル、アニメデータを特定する
	//chara読み込み
	res_obj_tbl[CLACT_U_CHAR_RES] = CLACT_U_ResManagerResAddArcChar(
						cnt_ptr->ResMan[CLACT_U_CHAR_RES],
						ARC_POKETHLON_POKE, char_arc_idx,
						FALSE, inActID, inVramType, cnt_ptr->HeapID);
	//pal読み込み		//確保だけなので、アーカイブは、実はなんでもいい
	res_obj_tbl[CLACT_U_PLTT_RES] = CLACT_U_ResManagerResAddArcPltt(
						cnt_ptr->ResMan[CLACT_U_PLTT_RES],
						ARC_TR_CASE_GRA, NARC_trainer_case_card_badge_NCLR,
						FALSE, inActID, inVramType, POKE_PALETTE_NUM, cnt_ptr->HeapID);

	//cell読み込み
	res_obj_tbl[CLACT_U_CELL_RES] = CLACT_U_ResManagerResAddArcKindCell(
						cnt_ptr->ResMan[CLACT_U_CELL_RES],
						ARC_POKETHLON_POKE, cel_arc_idx,
						FALSE, inActID, CLACT_U_CELL_RES, cnt_ptr->HeapID);

	//同じ関数でanim読み込み
	res_obj_tbl[CLACT_U_CELLANM_RES] = CLACT_U_ResManagerResAddArcKindCell(
						cnt_ptr->ResMan[CLACT_U_CELLANM_RES],
						ARC_POKETHLON_POKE, alanm_arc_idx,
						FALSE, inActID, CLACT_U_CELLANM_RES, cnt_ptr->HeapID);
	// リソースマネージャーから転送

	// Chara転送
	CLACT_U_CharManagerSetAreaCont( res_obj_tbl[CLACT_U_CHAR_RES] );

	// パレット転送
	CLACT_U_PlttManagerSet( res_obj_tbl[CLACT_U_PLTT_RES] );

	//テクスチャデータからキャラ・パレットを取得して転送
	{
		int trans_size;
		int size_w, size_h;
		int i;
		void *pFile;
		void *pRawData;
		u8 *start;
		NNSG3dResTex *tex;
		u32 vram;
		const NNSG2dImagePaletteProxy *pal_proxy;
		NNSG2dImageProxy	*img_proxy;
		NNSG2dCharacterData *chara_data;
		BOOL main_trans = FALSE;
		BOOL sub_trans = FALSE;

		//イメージプロキシ取得
		img_proxy = CLACT_U_CharManagerGetProxy(res_obj_tbl[CLACT_U_CHAR_RES]);
		//パレットプロキシ取得
		pal_proxy = CLACT_U_PlttManagerGetProxy(res_obj_tbl[CLACT_U_PLTT_RES],img_proxy);

		//キャラデータ取得
		chara_data = CLACT_U_ResManagerGetResObjResChar( res_obj_tbl[CLACT_U_CHAR_RES] );

		//VRAMタイプをチェック
		if (inVramType == NNS_G2D_VRAM_TYPE_MAX){
			main_trans = TRUE;
			sub_trans = TRUE;
		}else{
			if (inVramType == NNS_G2D_VRAM_TYPE_2DMAIN){
				main_trans = TRUE;
			}else{
				sub_trans = TRUE;
			}
		}

		{
			//アーカイブインデックス取得
			int arc_idx = GetMonsArcIdx(inMonsInfo->MonsNo, inMonsInfo->Form, inMonsInfo->Sex);
			//連れ歩きポケモンのテクスチャを読み込んでくる
			pFile = ArchiveDataLoadMalloc(	ARC_MMODEL, arc_idx, cnt_ptr->HeapID );
		}

		//セルタイプ別に転送サイズを変更
		if ( inMonsInfo->CellType ){
			trans_size = 64*64/2;
			size_w = 8;
			size_h = 8;
		}else{
			trans_size = 32*32/2;
			size_w = 4;
			size_h = 4;
		}

		// テクスチャファイルを取得
		tex = NNS_G3dGetTex((NNSG3dResFileHeader*) pFile );
		//テクスチャロウデータ取得
		start = (u8*)tex + tex->texInfo.ofsTex;
///		OS_Printf("texsize= %x\n",tex->texInfo.sizeTex);
#if 1
		for(i=0;i<8;i++){
			pRawData = &start[trans_size*i];
			//キャラデータ用のバッファにテクスチャのロウデータを1Ｄ変換して格納
			ChangesInto_RawData_1D_from_2D(pRawData, size_w, 0, 0, size_w, size_h,
					cnt_ptr->CharTempBuff);
///			OS_Printf("mons=%d\n",inMonsInfo->MonsNo);
			if (!inTrans){

				// キャラ詰めモード
				if(cnt_ptr->ChinkFlg && inMonsInfo->CellType){
					int count;
					// 1列キャラを詰める
					for(count=0; count<POKE_MAX_SIZE; count++ ){
						if( count < POKE_MAX_SIZE-size_w*ONE_CHR_BYTE ){
							cnt_ptr->CharTempBuff[count] = cnt_ptr->CharTempBuff[ count + size_w*ONE_CHR_BYTE ];
						}else{
							// 余白をクリア
							cnt_ptr->CharTempBuff[count] = 0;
						}
					}
				}

				DC_FlushRange( cnt_ptr->CharTempBuff, trans_size );	//転送するキャラ部分をフラッシュ
				//キャラデータバッファをあらかじめ転送していた場所に転送する
				if (main_trans){
					vram = NNS_G2dGetImageLocation( img_proxy, NNS_G2D_VRAM_TYPE_2DMAIN );
					GX_LoadOBJ(cnt_ptr->CharTempBuff, vram+(trans_size*i), trans_size);
				}
				if (sub_trans){
					vram = NNS_G2dGetImageLocation( img_proxy, NNS_G2D_VRAM_TYPE_2DSUB );
					GXS_LoadOBJ(cnt_ptr->CharTempBuff, vram+(trans_size*i), trans_size);
				}
			}
			{
				u8 *data;
				data = (u8 *)chara_data->pRawData;
				//抜き色検索用にテクスチャをダミーロウデータに転送しておく(VRAM転送のための用途も含む)
				MI_CpuCopyFast(cnt_ptr->CharTempBuff,&data[trans_size*i],trans_size);
			}
		}
#endif
#if 1
		//パレットロウデータ取得
		start = (u8*)tex + tex->plttInfo.ofsPlttData;
		//レアかどうかでオフセット変更
		if (inMonsInfo->Rare){
			start = &start[POKE_PALETTE_SIZE];
		}

		DC_FlushRange( start, POKE_PALETTE_SIZE );	//転送するパレット部分をフラッシュ
		if (main_trans){
			vram = NNS_G2dGetImagePaletteLocation(pal_proxy, NNS_G2D_VRAM_TYPE_2DMAIN);
			GX_LoadOBJPltt( start, vram, POKE_PALETTE_SIZE );	//32byte 1Palette
		}
		if (sub_trans){
			vram = NNS_G2dGetImagePaletteLocation(pal_proxy, NNS_G2D_VRAM_TYPE_2DSUB);
			GXS_LoadOBJPltt( start, vram, POKE_PALETTE_SIZE );	//32byte 1Palette;
		}
#endif
		sys_FreeMemoryEz( pFile );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * アクターセット
 *
 * @param	cnt_ptr			ポケモンアクターコントローラーポインタ
 * @param	inBGPriority	ＢＧプライオリティ
 * @param	inTrans			ＶＲＡＭ転送フラグ
 * @param	inDrawArea		描画画面
 * @param	inActID			アクターＩＤ
 * @param	inEntryPoint	登録場所
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetPCLActor( PCLACT_CNT_PTR cnt_ptr, const int inBGPriority, const BOOL inTrans,
							const NNS_G2D_VRAM_TYPE inDrawArea, const u8 inActID, const u8 inEntryPoint )
{
	CLACT_HEADER			cl_act_header;

	// セルアクターヘッダ作成
	CLACT_U_MakeHeader(	&cl_act_header,
						inActID, inActID, inActID, inActID,
						CLACT_U_HEADER_DATA_NONE, CLACT_U_HEADER_DATA_NONE,
						inTrans, inBGPriority,
						cnt_ptr->ResMan[CLACT_U_CHAR_RES],
						cnt_ptr->ResMan[CLACT_U_PLTT_RES],
						cnt_ptr->ResMan[CLACT_U_CELL_RES],
						cnt_ptr->ResMan[CLACT_U_CELLANM_RES],
						NULL,NULL);

	{
		//登録情報格納
		CLACT_ADD add;
		NNS_G2D_VRAM_TYPE draw_area;
		if (inDrawArea == NNS_G2D_VRAM_TYPE_MAX){
			draw_area = NNS_G2D_VRAM_TYPE_2DMAIN;
		}else{
			draw_area = inDrawArea;
		}

		add.ClActSet	= cnt_ptr->ClActSetPtr;
		add.ClActHeader	= &cl_act_header;
		add.heap		= cnt_ptr->HeapID;
		//↓この辺は後設定できるようにする
		add.mat.x		= 0;//FX32_CONST(32) ;
		add.mat.y		= 0;//FX32_CONST(96) ;		//画面は上下連続している
		add.mat.z		= 0;
		add.sca.x		= FX32_ONE;
		add.sca.y		= FX32_ONE;
		add.sca.z		= FX32_ONE;
		add.rot			= 0;
		add.pri			= 0;
		add.DrawArea	= draw_area;
		//↑

		cnt_ptr->PokeClActTbl[inEntryPoint].ClActWorkPtr = CLACT_Add(&add);
		GF_ASSERT(cnt_ptr->PokeClActTbl[inEntryPoint].ClActWorkPtr != NULL);
		CLACT_SetAnmFlag(cnt_ptr->PokeClActTbl[inEntryPoint].ClActWorkPtr,1);
		CLACT_AnmChg( cnt_ptr->PokeClActTbl[inEntryPoint].ClActWorkPtr,0 );
		CLACT_SetDrawFlag(cnt_ptr->PokeClActTbl[inEntryPoint].ClActWorkPtr, 0);	//非表示

	}
}

//--------------------------------------------------------------------------------------------
/**
 * アクターセットタスク
 *
 * @param	tcb			TCB
 * @param	work		ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void PLCActorSetTask(TCB_PTR tcb, void* work)
{
	PCLACT_SET_WORK *set_work = work;
	do{
		if ( SetSeq(set_work) ){
			//タスク終了
			set_work->CntPtr->ActSetFlg = TRUE;
			sys_FreeMemoryEz(work);
			TCB_Delete(tcb);
			return;
		}
	}while(set_work->Param.Quick);
}

//--------------------------------------------------------------------------------------------
/**
 * セットシーケンス
 *
 * @param	work		ワーク
 *
 * @return	BOOL		TRUE：処理終了	FALSE：処理継続
 */
//--------------------------------------------------------------------------------------------
static BOOL SetSeq(PCLACT_SET_WORK *work)
{
	switch(work->Seq){
	case PCLACT_SET_LOAD_TRANS:
		{
			u8 idx;
			idx = work->StartIdx + work->No;
			LoadTrance(work->CntPtr ,work->CntPtr->PokeClActTbl[idx].ResObjTbl,
				&work->InfoTbl[idx/*work->No*/], work->Param.ResVramType, idx, work->Param.Trans);

			//アクターにポケモン情報をセット
			work->CntPtr->PokeClActTbl[idx].MonsInfo = work->InfoTbl[idx/*work->No*/];

			//スペース取得
			work->CntPtr->PokeClActTbl[idx].Space = GetSpaceHeight(&work->CntPtr->PokeClActTbl[idx]);

			//キャラ詰めモード設定
			work->CntPtr->PokeClActTbl[idx].ChinkFlg = ( work->CntPtr->ChinkFlg && work->InfoTbl[idx].CellType );

			if ( work->CntPtr->PokeClActTbl[idx].ChinkFlg ){
				// １列詰めた分加算
				work->CntPtr->PokeClActTbl[idx].Space += 8;
			}

			//転送型でない場合はリソース破棄
			if (!work->Param.Trans){
				CLACT_U_RES_OBJ_PTR *res_obj_tbl;
				res_obj_tbl = work->CntPtr->PokeClActTbl[idx].ResObjTbl;
				CLACT_U_ResManagerResOnlyDelete( res_obj_tbl[CLACT_U_CHAR_RES] );
				CLACT_U_ResManagerResOnlyDelete( res_obj_tbl[CLACT_U_PLTT_RES] );
			}
			work->No++;
			if ( work->No >= work->EntryNum ){
				work->No = 0;
				work->Seq = PCLACT_SET_SET_ACT;
			}
		}
		break;
	case PCLACT_SET_SET_ACT:
		{
			u8 idx;
			idx = work->StartIdx + work->No;
			SetPCLActor( work->CntPtr, work->Param.BGPriority, work->Param.Trans,
					work->Param.DrawArea, idx, idx );
			work->No++;
			work->CntPtr->NowNum++;
			if ( work->No >= work->EntryNum){
				return TRUE;
			}
		}
	}

	return FALSE;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモングラフィックの抜き色以外の色が使用開始されるY座標の検出
 *
 * @param	poke_ptr		ポケモンアクターポインタ
 *
 * @return	抜き色以外の色が使用されるまでの縦スペース
 */
//--------------------------------------------------------------------------------------------
u8 PCLACT_GetSpaceHeight(PCLACT_PTR poke_ptr)
{
	return poke_ptr->Space;
#if 0
	u8 ans;
	u8 dot;
	u8 check_dot;
	MONS_INFO *mons_info;
	int size_h,size_w;
	int h,w;
	u8 *addr;

	//キャラデータ取得
	NNSG2dCharacterData* chara_data = CLACT_U_ResManagerGetResObjResChar( poke_ptr->ResObjTbl[CLACT_U_CHAR_RES] );
	mons_info = &poke_ptr->MonsInfo;

	//幅と高さ(キャラ)取得
	if ( mons_info->CellType ){
		size_w = 8;
		size_h = 8;
	}else{
		size_w = 4;
		size_h = 4;
	}

	ans = 0xff;
	addr = (u8*)chara_data->pRawData;

	//ポケモンの高さ（キャラ）分ループ
	for(h=0;h<size_h;h++){
		dot = 0xff;
		//ポケモンの幅（キャラ）分ループ
		for(w=0;w<size_w;w++){
			int ofs_byte = ONE_CHR_BYTE*(h*size_w+w);
			//1キャラチェック
			check_dot = CheckChar(addr, ofs_byte);
			if ( (check_dot!=0xff) && (dot>check_dot) ){
				dot = check_dot;
			}
		}
		//キャラ1ライン捜査終わった時点で、抜き色を見つけたか？
		if (dot!=0xff){	//抜き色以外を発見
			//捜査結果を算出
			ans = h*8+dot;
			break;
		}
	}

	GF_ASSERT(ans != 0xff);

	return ans;
#endif
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモングラフィックの抜き色以外の色が使用開始されるY座標の検出
 *
 * @param	poke_ptr		ポケモンアクターポインタ
 *
 * @return	抜き色以外の色が使用されるまでの縦スペース
 */
//--------------------------------------------------------------------------------------------
static u8 GetSpaceHeight(PCLACT_PTR poke_ptr)
{
	u8 ans;
	u8 dot;
	u8 check_dot;
	MONS_INFO *mons_info;
	int size_h,size_w;
	int h,w;
	u8 *addr;

	//キャラデータ取得
	NNSG2dCharacterData* chara_data = CLACT_U_ResManagerGetResObjResChar( poke_ptr->ResObjTbl[CLACT_U_CHAR_RES] );
	mons_info = &poke_ptr->MonsInfo;

	//幅と高さ(キャラ)取得
	if ( mons_info->CellType ){
		size_w = 8;
		size_h = 8;
	}else{
		size_w = 4;
		size_h = 4;
	}

	ans = 0xff;
	addr = (u8*)chara_data->pRawData;

	//ポケモンの高さ（キャラ）分ループ
	for(h=0;h<size_h;h++){
		dot = 0xff;
		//ポケモンの幅（キャラ）分ループ
		for(w=0;w<size_w;w++){
			int ofs_byte = ONE_CHR_BYTE*(h*size_w+w);
			//1キャラチェック
			check_dot = CheckChar(addr, ofs_byte);
			if ( (check_dot!=0xff) && (dot>check_dot) ){
				dot = check_dot;
			}
		}
		//キャラ1ライン捜査終わった時点で、抜き色を見つけたか？
		if (dot!=0xff){	//抜き色以外を発見
			//捜査結果を算出
			ans = h*8+dot;
			break;
		}
	}

	GF_ASSERT(ans != 0xff);

	return ans;
}

//----------------------------------------------------------------------------
/**
 *	@brief	キャラの抜き色チェック
 *
 *	@param	*data		キャラデータポインタ
 *	@param	inOfs		データオフセット(バイト単位)
 *
 *	@return	抜き色以外を検出した場合、検出した縦ドット値（検出しなかった場合は0xff）
 */
//-----------------------------------------------------------------------------
static u8 CheckChar(u8 *data, const int inOfs)
{
	u8 byte;
	u8 check;
	u8 i,j;
	u8 * check_data;
	check = 0xff;

	check_data = &data[inOfs];

	for(i=0;i<8;i++){
		//キャラの1ライン目(4バイト)をチェック
		for(j=0;j<4;j++){
			byte = (*check_data);
			if (byte != 0){
				check = i;
				break;
			}
			check_data++;	//1バイト進める
		}
		if (j!=4){
			//抜き色以外を検出
			break;
		}
	}

	return check;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンのアーカイブインデックスを返す
 * @param	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 * @param	inSex		性別
 *
 * @retval	idx			アーカイブインデックス
 */
//--------------------------------------------------------------
static int GetMonsArcIdx(const int inMonsNo, const u16 inFormNo, const int inSex)
{
	int idx;
	if ( (inMonsNo<=0) || (MONSNO_END<inMonsNo) ){
		idx = 1;
	}else{
		idx = NARC_mmodel_tsure_001_nsbtx + PairPokeIdx_GetIdx(inMonsNo);
		//モンスターナンバーだけからだと不十分なので、ここからさらに調べる（フォルムとか）
		//性別による描き違いをして、かつ複数フォルムナンバー所持ポケモンはいないので、
		//性別違いをまずキーにして分岐
		if (PairPokeIdx_GetSexDif(inMonsNo)){		//性別による描き違いがある
			if(inSex == PARA_FEMALE ){ //メスの場合
				idx += 1;	//ベースから1シフトしたところがメスのコード
			}
		}else{		//性別による描き違いがない
			//フォルムを調べる
			int form;
			if ( inFormNo > PairPokeIdx_GetFormNum(inMonsNo) ){
				form = 0;
			}else{
				form = inFormNo;
			}
			idx += form;
		}
	}

	return idx;
}

//--------------------------------------------------------------------------------------------
/**
 * セルアクターの拡縮率を指定
 *
 * @param	poke_ptr		ポケモンアクターポインタ
 * @param	sx				ｘ座標
 * @param	sy				ｙ座標
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void PCLACT_SetScale(PCLACT_PTR poke_ptr, f32 sx, f32 sy)
{
	CLACT_WORK_PTR act;
	VecFx32 vec = {0};

	act = PCLACT_GetClActWorkPtr(poke_ptr);
	vec.x = FX_F32_TO_FX32(sx);
	vec.y = FX_F32_TO_FX32(sy);

	CLACT_SetScale(act, &vec);
}

//-----------------------------------------------------------------------------
/**
 *	サイズが大きいポケモンのキャラを上に１キャラ詰めるモードにする(ポケ転送前に呼ぶこと)
 *
 *	@param	PCLACT_CNT_PTR cnt_ptr
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
void PCLACT_SetBigPokeChinkFlag( PCLACT_CNT_PTR cnt_ptr )
{
	GF_ASSERT( cnt_ptr );
	GF_ASSERT( cnt_ptr->ActSetFlg == 0 );

	cnt_ptr->ChinkFlg = 1;
}

//-----------------------------------------------------------------------------
/**
 *	キャラ詰めフラグ取得
 *
 *	@param	PCLACT_CNT_PTR cnt_ptr
 *
 *	@retval	BOOL		フラグ
 */
//-----------------------------------------------------------------------------
BOOL PCLACT_GetChinkFlag( PCLACT_CNT_PTR cnt_ptr )
{
	return cnt_ptr->ChinkFlg;
}

//-----------------------------------------------------------------------------
/**
 *	ポケモン個別のキャラ詰めフラグ取得
 *
 *	@param	PCLACT_CNT_PTR cnt_ptr
 *
 *	@retval	BOOL		フラグ
 */
//-----------------------------------------------------------------------------
BOOL PCLACT_GetPokeChinkFlag( PCLACT_PTR poke_ptr )
{
	return poke_ptr->ChinkFlg;
}
